home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
gfx
/
show
/
mpeg_player122.lha
/
amiga
/
amiga.c
next >
Wrap
C/C++ Source or Header
|
1992-12-11
|
12KB
|
626 lines
/*
* Implementation of the needed X functions for the
* Commodore Amiga
*
* Michael Balzer, December 1992
* balzer@heike.informatik.uni-dortmund.de
* m.balzer@aworld.(zer|sub.org|aworld.de)
*
* Release 1.0 (8.12.92):
* First release, needs os3.0, can only display on
* workbench or on 8 bit lores screen.
*
* Release 1.1 (11.12.92):
* Now also runs on system 2.x. Uses reqtools.library
* to ask the user for the screenmode. No HAM support yet.
* Version string: 1.22 means Amiga version 2 of mpeg_play 1.2
*
* TODO:
* - enhance color allocation for 2.x (error += usecount?)
* - implement mono style dithering
* - implement HAM mode
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <graphics/gfxbase.h>
#include <graphics/modeid.h>
#include <graphics/scale.h>
#include <graphics/graphint.h>
#include <dos/dos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/alib_protos.h>
#include <libraries/reqtools.h>
#include <proto/reqtools.h>
#define static
#define __inline
#include <inline/minreqtools.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#define ABS(a) (((int)(a)<0) ? -(a) : (a))
char *_version_ = "\0$VER: mpeg_play 1.22 (" __DATE__ ")";
/***********************************************************/
extern
struct Library *SysBase;
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct ReqToolsBase *ReqToolsBase = NULL;
struct Screen *mpeg_screen = NULL;
struct Window *mpeg_window = NULL;
struct RastPort *rp = NULL;
struct RastPort *temprp = NULL;
struct BitMap *tempbm = NULL;
struct ViewPort *vp = NULL;
char *amiga_option = NULL;
int offx, offy;
struct ColorMap *cm = NULL;
int used_colors[ 256 ];
int used_cnt = 0;
UWORD saved_colors[ 256 ];
int saved_cnt = 0;
int rev3;
/***********************************************************/
/* support routines for os revision 2 */
struct BitMap *myAllocBitMap( unsigned long sizex, unsigned long sizey,
unsigned long depth, unsigned long flags,
struct BitMap *friend_bitmap )
{
struct BitMap *bm;
bm = AllocVec( sizeof *bm, MEMF_CLEAR );
if( bm )
{
int i;
bm->BytesPerRow = (sizex + 15) >> 3 & 0xfffe;
bm->Rows = sizey;
bm->Depth = depth;
for( i=0; i<depth; i++ )
{
if( !(bm->Planes[i] = AllocRaster(sizex, sizey)) )
{
while( i-- ) FreeRaster( bm->Planes[i], sizex, sizey );
FreeVec( bm );
bm = 0;
break;
}
}
}
return bm;
}
void myFreeBitMap( struct BitMap *bm )
{
while( bm->Depth-- )
FreeRaster( bm->Planes[bm->Depth], bm->BytesPerRow*8, bm->Rows );
FreeVec( bm );
}
LONG myObtainBestPenA( struct ColorMap *cm, unsigned long r, unsigned long g,
unsigned long b, struct TagItem *tags )
{
int i, best, err, besterr;
int br, bg, bb;
int colors;
/* Farbwerte auf 4 Bit bringen */
r >>= 28; g >>= 28; b >>= 28;
/* Strategie: Zunächst die Farbe suchen, die der gewünschten
* am nächsten liegt. Wenn Farbe >= 4, Farbe auf Mittelwert zw.
* aktuellen und gesuchten Werten setzen und zurückgeben.
* Die unteren vier bleiben unverändert (Workbench).
*/
best = 0;
besterr = 100;
colors = 1 << rp->BitMap->Depth;
for( i=0; i<colors; i++ )
{
long rgb = GetRGB4( cm, i );
int cr, cg, cb;
cr = rgb >> 8 & 15;
cg = rgb >> 4 & 15;
cb = rgb & 15;
err = ABS( r - cr )
+ ABS( g - cg )
+ ABS( b - cb );
if( err < besterr )
{
best = i;
besterr = err;
br = cr;
bg = cg;
bb = cb;
}
}
if( best >= 4 && besterr != 0 )
{
/* Farbe anpassen */
SetRGB4( vp, best,
(r + br) / 2,
(g + bg) / 2,
(b + bb) / 2 );
}
return best;
}
void myReleasePen( struct ColorMap *cm, unsigned long n )
{
/* Farbe restaurieren */
long rgb = saved_colors[n];
int cr, cg, cb;
cr = rgb >> 8 & 15;
cg = rgb >> 4 & 15;
cb = rgb & 15;
SetRGB4( vp, n, cr, cg, cb );
}
/***********************************************************/
void amiga_closedown( void )
{
if( cm )
{
while( used_cnt-- )
if( rev3 ) ReleasePen( cm, used_colors[used_cnt] );
else myReleasePen( cm, used_colors[used_cnt] );
}
if( mpeg_window ) CloseWindow( mpeg_window );
if( mpeg_screen ) CloseScreen( mpeg_screen );
if( tempbm )
{
if( rev3 ) FreeBitMap( tempbm );
else myFreeBitMap( tempbm );
}
if( temprp ) FreeVec( temprp );
if( ReqToolsBase ) CloseLibrary( (struct Library *) ReqToolsBase );
if( IntuitionBase ) CloseLibrary( (struct Library *) IntuitionBase );
if( GfxBase ) CloseLibrary( (struct Library *) GfxBase );
}
Display *XOpenDisplay( _Xconst char *display_name )
{
struct rtScreenModeRequester *scrmodereq;
int y;
static struct TagItem windowtags[] =
{
{ WA_PubScreen, NULL },
{ WA_Left, 32 },
{ WA_Top, 32 },
{ WA_Width, 160 },
{ WA_Height, 120 },
{ WA_Title, (ULONG) "MPEG Window" },
{ WA_IDCMP, IDCMP_CLOSEWINDOW },
{ WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_NOCAREREFRESH | WFLG_ACTIVATE | WFLG_RMBTRAP },
{ WA_ScreenTitle, (ULONG) "MPEG Player V1.2, Amiga version by Michael Balzer 12/92" },
{ TAG_END }
};
if( !IntuitionBase )
{
/* install closedown routine */
atexit( amiga_closedown );
/* open shared libraries */
IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 0 );
if( !IntuitionBase ) exit(20);
GfxBase = (struct GfxBase *) OpenLibrary( "graphics.library", 0 );
if( !GfxBase ) exit(20);
ReqToolsBase = (struct ReqToolsBase *) OpenLibrary( "reqtools.library", 38 );
if( !ReqToolsBase )
{
puts( "I need reqtools.library v38!\n" );
exit(20);
}
rev3 = (GfxBase->LibNode.lib_Version >= 39);
/* open some display */
if( strcmp(amiga_option, "window") == 0 )
{
/* try to open a window */
struct Screen *s;
if( s = LockPubScreen(NULL) )
{
windowtags[0].ti_Data = (ULONG) s;
mpeg_window = OpenWindowTagList( NULL, windowtags );
if( mpeg_window )
{
rp = mpeg_window->RPort;
offx = mpeg_window->BorderLeft;
offy = mpeg_window->BorderTop;
}
UnlockPubScreen( NULL, s );
}
}
/* fallback to own screen */
if( !mpeg_window )
{
if( scrmodereq = rtAllocRequestA( RT_SCREENMODEREQ, NULL ) )
{
if( rtScreenModeRequest( scrmodereq, "MPEG: Pick a screen mode",
RTSC_Flags, SCREQF_DEPTHGAD|SCREQF_SIZEGADS|SCREQF_AUTOSCROLLGAD|SCREQF_OVERSCANGAD,
TAG_END ) )
{
mpeg_screen = OpenScreenTags( NULL,
SA_Title, (ULONG) "MPEG Screen",
SA_DisplayID, scrmodereq->DisplayID,
SA_Width, scrmodereq->DisplayWidth,
SA_Height, scrmodereq->DisplayHeight,
SA_Depth, scrmodereq->DisplayDepth,
SA_Overscan, scrmodereq->OverscanType,
SA_AutoScroll, scrmodereq->AutoScroll,
SA_Quiet, TRUE,
SA_Interleaved, TRUE,
SA_SharePens, TRUE,
TAG_END );
/* Autoscroll would need a backdrop window, but that
* would posssibly slow it down even more...
*/
}
rtFreeRequest( scrmodereq );
if( !mpeg_screen )
exit(20);
rp = &mpeg_screen->RastPort;
offx = offy = 0;
}
else
{
puts( "Out of memory!" );
exit(0);
}
}
/* Viewport und Colormap bestimmen */
vp = (mpeg_screen)
? &mpeg_screen->ViewPort
: &mpeg_window->WScreen->ViewPort;
cm = vp -> ColorMap;
/* Farben sichern */
saved_cnt = 1 << rp->BitMap->Depth;
for( y=0; y<saved_cnt; y++ )
saved_colors[y] = GetRGB4( cm, y );
/* temporären Rastport aufsetzen */
temprp = AllocVec( sizeof *temprp, MEMF_ANY );
memcpy( temprp, rp, sizeof *temprp );
temprp->Layer = 0;
if( rev3 )
tempbm = AllocBitMap( rp->BitMap->BytesPerRow * 8, 1,
rp->BitMap->Depth, NULL, rp->BitMap );
else
tempbm = myAllocBitMap( rp->BitMap->BytesPerRow * 8, 1,
rp->BitMap->Depth, NULL, rp->BitMap );
temprp->BitMap = tempbm;
}
return (Display *) 1;
}
int XDefaultScreen( Display *display )
{
return 1;
}
XFlush( Display *display )
{
}
/***************************************************************/
Window XRootWindow(
Display* display,
int screen_number )
{
return 1;
}
Window XCreateSimpleWindow(
Display* display,
Window parent,
int x,
int y,
unsigned int width,
unsigned int height,
unsigned int border_width,
unsigned long border,
unsigned long background )
{
return 1;
}
Window XCreateWindow(
Display* display,
Window parent,
int x,
int y,
unsigned int width,
unsigned int height,
unsigned int border_width,
int depth,
unsigned int class,
Visual* visual,
unsigned long valuemask,
XSetWindowAttributes* attributes )
{
/* Generiert Fenster auf Full-Color-Display */
/* (HAM Support?) */
return 0;
}
XSetStandardProperties(
Display* display,
Window w,
_Xconst char* window_name,
_Xconst char* icon_name,
Pixmap icon_pixmap,
char** argv,
int argc,
XSizeHints* hints )
{
}
XMapWindow(
Display* display,
Window w )
{
}
XResizeWindow(
Display* display,
Window w,
unsigned int width,
unsigned int height )
{
if( mpeg_screen ) return;
ChangeWindowBox( mpeg_window,
mpeg_window->LeftEdge, mpeg_window->TopEdge,
width + mpeg_window->BorderLeft + mpeg_window->BorderRight,
height + mpeg_window->BorderTop + mpeg_window->BorderBottom
);
}
/***************************************************************/
Status XMatchVisualInfo(
Display* display,
int screen,
int depth,
int class,
XVisualInfo* vinfo_return )
{
return( depth <= 8 );
}
XVisualInfo *XGetVisualInfo(
Display* display,
long vinfo_mask,
XVisualInfo* vinfo_template,
int* nitems_return )
{
*nitems_return = 0;
return vinfo_template;
}
GC XCreateGC(
Display* display,
Drawable d,
unsigned long valuemask,
XGCValues* values )
{
return (GC) 1;
}
/***************************************************************/
XImage *XCreateImage(
Display* display,
Visual* visual,
unsigned int depth,
int format,
int offset,
char* data,
unsigned int width,
unsigned int height,
int bitmap_pad,
int bytes_per_line )
{
XImage *xi;
if( xi = calloc(sizeof *xi, 1) )
{
xi->width = width;
xi->height = height;
xi->depth = depth;
xi->f.destroy_image = (int (*)()) free;
}
return xi;
}
XPutImage(
Display* display,
Drawable d,
GC gc,
XImage* image,
int src_x,
int src_y,
int dest_x,
int dest_y,
unsigned int width,
unsigned int height )
{
struct IntuiMessage *imsg;
ULONG class;
/* in image->data ist das Bild als Folge von Bytes,
* display zeigt auf nix,
* d und gc sind egal,
* src_? und dest_? sind hier immer 0,
* width und height stimmen mit den Bilddimensionen überein
* (oder sollten zumindest...)
*/
WritePixelArray8( rp, offx, offy, offx+width-1, offy+height-9, image->data, temprp );
/* y-Height - 9 because of 8 lines of random pixels beyond the pic */
if( mpeg_window )
{
while( imsg = (struct IntuiMessage *) GetMsg(mpeg_window->UserPort) )
{
class = imsg->Class;
ReplyMsg( (struct Message *) imsg );
if( class == CLOSEWINDOW )
exit( 0 );
}
}
}
/***************************************************************/
Colormap XCreateColormap(
Display* display,
Window w,
Visual* visual,
int alloc )
{
return 1;
}
Colormap XDefaultColormap(
Display* display,
int screen_number )
{
return 1;
}
Status XAllocColor(
Display* display,
Colormap colormap,
XColor* xcolor )
{
long color;
if( rev3 )
color = ObtainBestPenA( cm,
xcolor->red << 16, xcolor->green << 16, xcolor->blue << 16,
NULL );
else
color = myObtainBestPenA( cm,
xcolor->red << 16, xcolor->green << 16, xcolor->blue << 16,
NULL );
used_colors[ used_cnt++ ] = color;
xcolor->pixel = color;
return color;
}
/***************************************************************/
XFree( void *data )
{
}